﻿using ERP.ERPSystem.WarehouseManagement.Dto;
using ERP.Team.WarehouseManagement;
using ERP.Team.ProductionSystem;
using ERP.ERPSystem.ProductionSystem.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;

namespace ERP.ERPSystem.WarehouseManagement
{
    /// <summary>
    /// 仓储管理-库存信息-库存现有量-xzc
    /// </summary>
    public class InventoryHandServices: ApplicationService,IInventoryHandServices
    {
        private readonly IRepository<Inventory> _inventoryRepository;
        private readonly IRepository<MaterialType> _materialTypeRepository;

        public InventoryHandServices(IRepository<Inventory> inventoryRepository, IRepository<MaterialType> materialTypeRepository)
        {
            _inventoryRepository = inventoryRepository;
            _materialTypeRepository = materialTypeRepository;
        }
        /// <summary>
        /// 新增库存现有量 
        /// </summary>
        /// <param name="inventoryDto"></param>
        /// <returns></returns>
        public async Task<int> AddInventory(InventoryDto inventoryDto)
        {
            var i = ObjectMapper.Map<InventoryDto,Inventory>(inventoryDto);
            var inventoryList = await _inventoryRepository.InsertAsync(i);
            return inventoryList == null ? 0 : 1;
        }
        /// <summary>
        /// 更新库存现有量 
        /// </summary>
        /// <param name="inventoryDto"></param>
        /// <returns></returns>
        public async Task<int> UpateInventory(InventoryDto inventoryDto)
        {
            var i = ObjectMapper.Map<InventoryDto, Inventory>(inventoryDto);
            var inventoryList = await _inventoryRepository.UpdateAsync(i);
            return inventoryList == null ? 0 : 1;
        }
        /// <summary>
        /// 删除库存现有量 
        /// </summary>
        /// <param name="inventoryDto"></param>
        /// <returns></returns>
        public async Task DeleteInventory(int id)
        {
            await _inventoryRepository.DeleteAsync(m=>m.Id == id);
        }
        /// <summary>
        /// 查询库存现有量 
        /// </summary>
        /// <param name="getissuingmaterialsdto"></param>
        /// <returns></returns>
        public async Task<List<Inventory>> GetInventory(GetInventorysDto getinventorysdto)
        {
            var inventorysList = await _inventoryRepository.GetListAsync();

            inventorysList = inventorysList.WhereIf(getinventorysdto.ProductItem.HasValue && getinventorysdto.ProductItem.Value > 0, m => m.ProductItem == getinventorysdto.ProductItem.Value).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.ProductName), m => m.ProductName.Contains(getinventorysdto.ProductName)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Storage), m => m.Storage.Contains(getinventorysdto.Storage)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Warehouse), m => m.Warehouse.Contains(getinventorysdto.Warehouse)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierNumber), m => m.SupplierNumber.Contains(getinventorysdto.SupplierNumber)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierName), m => m.SupplierName.Contains(getinventorysdto.SupplierName)).ToList();
            inventorysList = inventorysList.WhereIf(getinventorysdto.Storagevalidity.HasValue, m => m.Storagevalidity.Date == getinventorysdto.Storagevalidity.Value.Date).ToList();
            return inventorysList;

        }

        /// <summary>
        /// 获取物料分类树形结构
        /// </summary>
        /// <returns></returns>
        public async Task<List<MaterialTypeTreeDto>> GetMaterialTypeTree()
        {
            var materialTypes = await _materialTypeRepository.GetListAsync();
            
            // 获取根节点（ParentId为空或0的节点）
            var rootItems = materialTypes.Where(x => x.ParentId == null || x.ParentId == 0)
                                       .OrderBy(x => x.Index)
                                       .ToList();

            var treeList = new List<MaterialTypeTreeDto>();

            foreach (var item in rootItems)
            {
                var treeNode = new MaterialTypeTreeDto
                {
                    Id = item.Id,
                    Title = item.MaterialTypeName,
                    ParentId = item.ParentId,
                    Index = item.Index,
                    Spread = true
                };

                // 递归构建子节点
                BuildChildren(treeNode, materialTypes);
                treeList.Add(treeNode);
            }

            return treeList;
        }

        /// <summary>
        /// 递归构建子节点
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="allItems"></param>
        private void BuildChildren(MaterialTypeTreeDto parent, List<MaterialType> allItems)
        {
            var children = allItems.Where(x => x.ParentId == parent.Id)
                                  .OrderBy(x => x.Index)
                                  .ToList();

            foreach (var child in children)
            {
                var childNode = new MaterialTypeTreeDto
                {
                    Id = child.Id,
                    Title = child.MaterialTypeName,
                    ParentId = child.ParentId,
                    Index = child.Index,
                    Spread = true
                };

                // 递归构建子节点
                BuildChildren(childNode, allItems);
                parent.Children.Add(childNode);
            }
        }

        /// <summary>
        /// 根据物料分类ID查询库存数据
        /// </summary>
        /// <param name="materialTypeId"></param>
        /// <param name="getinventorysdto"></param>
        /// <returns></returns>
        public async Task<List<Inventory>> GetInventoryByMaterialType(int? materialTypeId, GetInventorysDto getinventorysdto)
        {
            var inventorysList = await _inventoryRepository.GetListAsync();
            
            // 如果指定了物料分类ID，则通过MaterialType.Id与Inventory.ProductItem直接匹配
            if (materialTypeId.HasValue && materialTypeId.Value > 0)
            {
                // 获取当前分类及其所有子分类的ID
                var materialTypeIds = await GetAllChildMaterialTypeIds(materialTypeId.Value);
                materialTypeIds.Add(materialTypeId.Value); // 添加当前分类ID
                
                // 转换MaterialType ID为字符串列表，同时支持int和string类型的ProductItem匹配
                var materialTypeIdStrings = materialTypeIds.Select(id => id.ToString()).ToList();
                
                // 尝试多种匹配方式以处理数据类型不一致问题
                var matchedInventories = inventorysList.Where(inv => 
                {
                    // 方式1: 直接整数匹配（如果ProductItem是int类型）
                    if (materialTypeIds.Contains(inv.ProductItem))
                        return true;
                    
                    // 方式2: 字符串匹配（如果ProductItem实际存储的是字符串）
                    var productItemStr = inv.ProductItem.ToString();
                    if (materialTypeIdStrings.Contains(productItemStr))
                        return true;
                    
                    // 方式3: 尝试解析ProductItem为字符串后匹配
                    try
                    {
                        if (int.TryParse(productItemStr, out int productItemInt))
                        {
                            return materialTypeIds.Contains(productItemInt);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogWarning($"ProductItem转换异常: {ex.Message}, ProductItem值: {inv.ProductItem}");
                    }
                    
                    return false;
                }).ToList();
                
                inventorysList = matchedInventories;
            }

            // 应用其他筛选条件
            inventorysList = inventorysList.WhereIf(getinventorysdto.ProductItem.HasValue && getinventorysdto.ProductItem.Value > 0, m => m.ProductItem == getinventorysdto.ProductItem.Value).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.ProductName), m => m.ProductName.Contains(getinventorysdto.ProductName)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Storage), m => m.Storage.Contains(getinventorysdto.Storage)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Warehouse), m => m.Warehouse.Contains(getinventorysdto.Warehouse)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierNumber), m => m.SupplierNumber.Contains(getinventorysdto.SupplierNumber)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierName), m => m.SupplierName.Contains(getinventorysdto.SupplierName)).ToList();
            inventorysList = inventorysList.WhereIf(getinventorysdto.Storagevalidity.HasValue, m => m.Storagevalidity.Date == getinventorysdto.Storagevalidity.Value.Date).ToList();
            
            return inventorysList;
        }

        /// <summary>
        /// 获取所有子分类ID
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private async Task<List<int>> GetAllChildMaterialTypeIds(int parentId)
        {
            var allMaterialTypes = await _materialTypeRepository.GetListAsync();
            var childIds = new List<int>();

            GetChildIds(parentId, allMaterialTypes, childIds);

            return childIds;
        }

        /// <summary>
        /// 递归获取子分类ID
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="allMaterialTypes"></param>
        /// <param name="childIds"></param>
        private void GetChildIds(int parentId, List<MaterialType> allMaterialTypes, List<int> childIds)
        {
            var children = allMaterialTypes.Where(x => x.ParentId == parentId).ToList();

            foreach (var child in children)
            {
                childIds.Add(child.Id);
                GetChildIds(child.Id, allMaterialTypes, childIds);
            }
        }

        /// <summary>
        /// 根据物料分类ID直接匹配ProductItem查询库存数据
        /// </summary>
        /// <param name="materialTypeId"></param>
        /// <param name="getinventorysdto"></param>
        /// <returns></returns>
        public async Task<List<Inventory>> GetInventoryByProductItem(int materialTypeId, GetInventorysDto getinventorysdto)
        {
            var inventorysList = await _inventoryRepository.GetListAsync();

            // 获取包含当前分类和所有子分类的ID列表
            var materialTypeIds = await GetAllChildMaterialTypeIds(materialTypeId);
            materialTypeIds.Add(materialTypeId); // 添加当前分类ID

            // 转换MaterialType ID为字符串列表，同时支持int和string类型的ProductItem匹配
            var materialTypeIdStrings = materialTypeIds.Select(id => id.ToString()).ToList();

            // 使用多种匹配方式以处理数据类型不一致问题
            inventorysList = inventorysList.Where(inv => 
            {
                // 方式1: 直接整数匹配（如果ProductItem是int类型）
                if (materialTypeIds.Contains(inv.ProductItem))
                    return true;
                
                // 方式2: 字符串匹配（如果ProductItem实际存储的是字符串）
                var productItemStr = inv.ProductItem.ToString();
                if (materialTypeIdStrings.Contains(productItemStr))
                    return true;
                
                // 方式3: 尝试解析ProductItem为字符串后匹配
                try
                {
                    if (int.TryParse(productItemStr, out int productItemInt))
                    {
                        return materialTypeIds.Contains(productItemInt);
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning($"ProductItem转换异常: {ex.Message}, ProductItem值: {inv.ProductItem}");
                }
                
                return false;
            }).ToList();

            // 应用其他筛选条件
            inventorysList = inventorysList.WhereIf(getinventorysdto.ProductItem.HasValue && getinventorysdto.ProductItem.Value > 0, m => m.ProductItem == getinventorysdto.ProductItem.Value).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.ProductName), m => m.ProductName.Contains(getinventorysdto.ProductName)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Storage), m => m.Storage.Contains(getinventorysdto.Storage)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.Warehouse), m => m.Warehouse.Contains(getinventorysdto.Warehouse)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierNumber), m => m.SupplierNumber.Contains(getinventorysdto.SupplierNumber)).ToList();
            inventorysList = inventorysList.WhereIf(!string.IsNullOrEmpty(getinventorysdto.SupplierName), m => m.SupplierName.Contains(getinventorysdto.SupplierName)).ToList();
            inventorysList = inventorysList.WhereIf(getinventorysdto.Storagevalidity.HasValue, m => m.Storagevalidity.Date == getinventorysdto.Storagevalidity.Value.Date).ToList();

            return inventorysList;
        }

        /// <summary>
        /// 获取库存数据和物料分类的调试信息
        /// </summary>
        /// <returns></returns>
        public async Task<object> GetInventoryDebugInfo()
        {
            var inventorysList = await _inventoryRepository.GetListAsync();
            var materialTypes = await _materialTypeRepository.GetListAsync();
            
            var debugInfo = new
            {
                InventoryCount = inventorysList.Count,
                MaterialTypeCount = materialTypes.Count,
                InventorySample = inventorysList.Take(5).Select(inv => new
                {
                    inv.Id,
                    ProductItem = inv.ProductItem,
                    ProductItemType = inv.ProductItem.GetType().Name,
                    ProductItemValue = inv.ProductItem.ToString(),
                    inv.ProductName,
                    inv.Warehouse
                }).ToList(),
                MaterialTypeSample = materialTypes.Take(10).Select(mt => new
                {
                    mt.Id,
                    mt.MaterialTypeName,
                    mt.ParentId
                }).ToList(),
                UniqueProductItems = inventorysList.Select(inv => inv.ProductItem).Distinct().OrderBy(x => x).ToList(),
                MaterialTypeIds = materialTypes.Select(mt => mt.Id).OrderBy(x => x).ToList(),
                ProductItemTypes = inventorysList.Select(inv => inv.ProductItem.GetType().Name).Distinct().ToList(),
                // 检查特定ID的匹配情况
                Id7Matches = inventorysList.Where(inv => 
                    inv.ProductItem == 7 || 
                    inv.ProductItem.ToString() == "7"
                ).Select(inv => new {
                    inv.Id,
                    ProductItem = inv.ProductItem,
                    ProductItemType = inv.ProductItem.GetType().Name,
                    inv.ProductName
                }).ToList()
            };
            
            return debugInfo;
        }
    }
}
